/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.ac.iie.pre.parser.global;

import cn.ac.iie.di.datadock.rdata.exchange.client.core.REFieldType;
import cn.ac.iie.di.datadock.rdata.exchange.client.v1.REMessage;
import cn.ac.iie.pre.parser.config.ConfigureUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import org.apache.commons.configuration2.FileBasedConfiguration;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.log4j.Logger;


/**
 * @author QJP
 */
public class GlobalParas {

    public static Logger LOG = Logger.getLogger(GlobalParas.class);

    //properties name
    public final static String LOG4_CONFIGURATION = "log4j.properties";
    public final static String DEFAULT_CONFIGURATION = "config.properties";

    //configuration.properties parameters
    public static String SOURCE_DIR;   
    public static String UNTAR_SUS_SUFFIX;
    public static String READ_SUS_SUFFIX;
    
    public static ArrayBlockingQueue<String> FILES_NAME_QUEUE;
    
    public static List<Object> MSG_TYPES_NAME;
    public static Map<String,REMessage> MSG_TYPE_MAP;
    
    public static Map<Object,ArrayBlockingQueue<REMessage>> SEND_QUEUE_MAP;
    
    public static String SEND_CONSUMER_NAMESERVER;
    public static String SEND_CONSUMER_TOPIC;
    
    public static int READ_RECORD_THREAD_NUM;
    
    public static int SEND_MQ_MSG_NUM;
    public static int SEND_MQ_TIME_OUT;
    
    private static volatile GlobalParas instanceDefConf;

    public GlobalParas(String confPropertiesName) throws ConfigurationException {
        String confPropertiesPath = ClassLoader.getSystemClassLoader().getResource(confPropertiesName).getFile();
        ConfigureUtil configureUtil = new ConfigureUtil();
        FileBasedConfiguration configuration = configureUtil.initConfiguration(confPropertiesPath);
        if (confPropertiesName.equals(DEFAULT_CONFIGURATION)) {
            initConf(configuration);
        }
    }

    public static GlobalParas getIstance(String confPropertiesName) throws ConfigurationException {
        if (confPropertiesName.equals(DEFAULT_CONFIGURATION)) {
            if (instanceDefConf == null) {
                synchronized (GlobalParas.class) {
                    if (instanceDefConf == null) {
                        instanceDefConf = new GlobalParas(confPropertiesName);
                    }
                }
            }
            return instanceDefConf;
        } else {
            LOG.error("Could Not Find Configuration: " + confPropertiesName);
            return null;
        }
    }

    public static void initConf(FileBasedConfiguration configuration) {
        SOURCE_DIR=configuration.getString("source.dir");
        UNTAR_SUS_SUFFIX=configuration.getString("untar.sus.suffix");
        READ_SUS_SUFFIX=configuration.getString("read.sus.suffix");
        FILES_NAME_QUEUE=new ArrayBlockingQueue<>(configuration.getInt("files.queue.num"));
        
        MSG_TYPES_NAME=configuration.getList("msg.types.name");
        MSG_TYPE_MAP=new HashMap<>();
        
        
        SEND_QUEUE_MAP=new HashMap<>();
        initMsgTypeMap(configuration);
        
        SEND_CONSUMER_NAMESERVER=configuration.getString("send.consumer.nameserver");
        SEND_CONSUMER_TOPIC=configuration.getString("send.consumer.topic");
        
        READ_RECORD_THREAD_NUM=configuration.getInt("read.record.thread.num");
        
        SEND_MQ_MSG_NUM=configuration.getInt("send.mq.msg.num");
        SEND_MQ_TIME_OUT=configuration.getInt("send.mq.time.out");
    }
    
    public static void initMsgTypeMap(FileBasedConfiguration configuration){
        for(Object msgTypeName:MSG_TYPES_NAME){
             List<Object> columnTypeList=configuration.getList("msg.type."+msgTypeName.toString());
             List<String> columList=new ArrayList<>();
             List<REFieldType> typeList=new ArrayList<>();
             
             for(Object aColumnType:columnTypeList){
                 try{
                    columList.add(aColumnType.toString().split(":")[0]);
                    typeList.add(typeCovtToREFiledtype(aColumnType.toString().split(":")[1]));
                 }catch(Exception ex){
                     LOG.error(aColumnType);
                 }
                 
             }

             REMessage msg=new REMessage(columList.toArray(new String[columList.size()]), typeList.toArray(new REFieldType[typeList.size()]), new ArrayList<Object[]>(), "", new HashMap<String, String>());
             MSG_TYPE_MAP.put(msgTypeName.toString(), msg);
             
             SEND_QUEUE_MAP.put(msgTypeName, new ArrayBlockingQueue<REMessage>(configuration.getInt("send.queue.size")));
        }
       
    }
    public static REFieldType typeCovtToREFiledtype(String type) {
        switch (type){
            case "string":
                return REFieldType.String;
            case "strings":
                return REFieldType.Strings;
            case "long":
                return REFieldType.Long;
            case "structs":
                return REFieldType.Structs;
            default:
                return null;
        }
    }

}
